#include "video_gui.h"
#include "lvgl/lvgl.h"
#include <stdlib.h>

#define TOP_CONT_HIGHT 35
#define PLAY_WINDOW_BOTTOM_CONT_HEIGHT 80

typedef struct
{
  lv_obj_t *screen;
  lv_obj_t *bottom_cont;
  lv_obj_t *pause_img;
  lv_obj_t *list_img;
  lv_obj_t *prog_slider;
  lv_obj_t *video_label;
  lv_obj_t *time_label;
  lv_obj_t *volume_slider;
} play_window_t;

LV_IMG_DECLARE(butterfly)
LV_IMG_DECLARE(list)
LV_IMG_DECLARE(pause)
LV_IMG_DECLARE(playing)
LV_IMG_DECLARE(item_idle)
LV_IMG_DECLARE(item_playing)
LV_IMG_DECLARE(volume)

LV_FONT_DECLARE(lv_font_miao_16)
LV_FONT_DECLARE(lv_font_miao_18)
LV_FONT_DECLARE(lv_font_miao_25)
LV_FONT_DECLARE(lv_font_miao_30)

static void drag_event_handler(lv_event_t *e);
static void video_list_btn_event_cb(lv_event_t *e);
static void play_window_bottom_pause_btn_click_event_cb(lv_event_t *e);
static void play_window_bottom_list_btn_click_event_cb(lv_event_t *e);
static void video_progress_slider_event_cb(lv_event_t *e);
static void volume_slider_event_cb(lv_event_t *e);
static void black_screen_click_event_handler(lv_event_t *e);
static void set_clearscreen_flag_timer_cb(lv_timer_t *t);
static void clear_screen_timer_cb(lv_timer_t *t);

// gui回调函数集
static gui_opt_t gui_opts;

// LCD分辨率
static uint32_t lcd_w = 480;
static uint32_t lcd_h = 272;

// 背景图片
static lv_obj_t *back_img;

// 退出按钮
static lv_obj_t *exit_btn;

// 视频列表顶部容器
static lv_obj_t *top_cont;

// 视频列表list
static lv_obj_t *video_list;

// 保存当前正在播放的视频对应的list btn
static lv_obj_t *playing_video_btn = NULL;

// 播放视频窗口
static play_window_t play_window;

// 播放进度slider是否被按下
static bool video_slider_pressed = false;

//当前是否清屏
static bool video_screen_is_clean = false;

//清屏定时器
static lv_timer_t *clear_screen_timer = NULL;

/**
  *@brief 初始化界面UI
  ×@param opts UI回调函数集合
  */
void video_gui_init(gui_opt_t *opts)
{
  lv_obj_t *act = lv_scr_act();

  if (opts != NULL) // 设置回调函数集合
    memcpy(&gui_opts, opts, sizeof(gui_opt_t));

  // 获取显示设备分辨率
  lcd_w = lv_disp_get_hor_res(NULL);
  lcd_h = lv_disp_get_ver_res(NULL);

  // 创建背景图片
  back_img = lv_img_create(act);
  lv_img_set_src(back_img, "S:./res/background/videobg.bin");
  lv_obj_set_size(back_img, lcd_w, lcd_h);
  lv_obj_clear_flag(back_img, LV_OBJ_FLAG_SCROLLABLE);
  lv_obj_set_style_bg_color(back_img, lv_color_hex(0x000000), LV_STATE_DEFAULT);

  // 创建视频列表顶部容器
  top_cont = lv_obj_create(back_img);
  lv_obj_set_size(top_cont, lcd_w, TOP_CONT_HIGHT);
  lv_obj_clear_flag(top_cont, LV_OBJ_FLAG_SCROLLABLE);
  lv_obj_set_style_bg_color(top_cont, lv_color_hex(0x000000), LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(top_cont, LV_OPA_30, LV_STATE_DEFAULT);
  lv_obj_set_style_border_width(top_cont, 0, LV_STATE_DEFAULT);
  lv_obj_set_style_pad_all(top_cont, 0, LV_STATE_DEFAULT);
  lv_obj_set_style_radius(top_cont, 0, LV_STATE_DEFAULT);

  lv_obj_t *title_label = lv_label_create(top_cont);
  lv_obj_set_style_text_font(title_label, &lv_font_miao_30, LV_STATE_DEFAULT);
  lv_obj_set_style_text_color(title_label, lv_color_hex(0xeaeaea), LV_STATE_DEFAULT);
  lv_label_set_text(title_label, "视频播放器");
  lv_obj_center(title_label);

  // 创建视频列表list
  video_list = lv_list_create(back_img);
  lv_obj_set_size(video_list, lcd_w, lcd_h - TOP_CONT_HIGHT);
  lv_obj_align_to(video_list, top_cont, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
  lv_obj_set_style_bg_opa(video_list, LV_OPA_TRANSP, LV_STATE_DEFAULT);      // 设置背景透明度
  lv_obj_set_style_bg_color(video_list, lv_color_black(), LV_STATE_DEFAULT); // 背景黑色
  lv_obj_set_style_border_opa(video_list, LV_OPA_TRANSP, LV_STATE_DEFAULT);  // 设置边框透明
  lv_obj_set_style_radius(video_list, 0, LV_STATE_DEFAULT);                  // 边框圆角为0

  // 创建退出按钮
  exit_btn = lv_obj_create(back_img);
  lv_obj_set_size(exit_btn, 70, 70);
  lv_obj_set_pos(exit_btn, 935, 267);
  lv_obj_clear_flag(exit_btn, LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
  lv_obj_set_style_radius(exit_btn, 35, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(exit_btn, lv_color_hex(0xffffff), LV_STATE_DEFAULT);
  lv_obj_set_style_border_opa(exit_btn, LV_OPA_TRANSP, LV_STATE_DEFAULT); // A边框透明
  lv_obj_set_style_bg_opa(exit_btn, LV_OPA_50, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(exit_btn, LV_OPA_90, LV_STATE_PRESSED);

  lv_obj_t *img = lv_img_create(exit_btn);
  lv_img_set_src(img, &butterfly);
  lv_obj_align(img, LV_ALIGN_CENTER, 0, 0);
  lv_obj_add_flag(img, LV_OBJ_FLAG_EVENT_BUBBLE);

  lv_obj_add_event_cb(exit_btn, drag_event_handler, LV_EVENT_PRESSING, NULL);
  if (gui_opts.exit_cb != NULL)
    lv_obj_add_event_cb(exit_btn, gui_opts.exit_cb, LV_EVENT_SHORT_CLICKED, NULL);
}

/**
 *@brief 添加一个视频到列表
 *@param name 视频文件名称
 */
void video_gui_add_video_list(const char *name)
{
  // 添加一个按钮到list
  lv_obj_t *btn = lv_list_add_btn(video_list, &item_idle, name);
  lv_obj_set_flex_align(btn, LV_FLEX_FLOW_ROW, LV_FLEX_ALIGN_CENTER, LV_FLEX_FLOW_ROW);
  lv_obj_set_style_bg_opa(btn, LV_OPA_TRANSP, LV_STATE_DEFAULT); // 设置背景透明
  lv_obj_set_style_bg_opa(btn, LV_OPA_30, LV_STATE_PRESSED);     // 设置背景透明度(按下时)
  lv_obj_set_style_text_color(btn, lv_color_hex(0x82cef5), LV_STATE_DEFAULT);
  lv_obj_set_style_text_font(btn, &lv_font_miao_25, LV_STATE_DEFAULT); // 设置字体
  lv_obj_add_event_cb(btn, video_list_btn_event_cb, LV_EVENT_SHORT_CLICKED, NULL);

  int len = strlen(name) + 1;
  char *video_name = malloc(len);
  strcpy(video_name, name);

  lv_obj_set_user_data(btn, video_name);
}

/**
 *@brief 创建播放窗口
 */
void video_gui_create_play_window(void)
{
  // 创建播放黑幕
  lv_obj_t *black_screen = lv_obj_create(lv_scr_act());
  lv_obj_set_size(black_screen, lcd_w, lcd_h);
  lv_obj_clear_flag(black_screen, LV_OBJ_FLAG_SCROLLABLE);
  lv_obj_set_style_bg_color(black_screen, lv_color_hex(0x000000), LV_STATE_DEFAULT);
  lv_obj_set_style_border_width(black_screen, 0, LV_STATE_DEFAULT);
  lv_obj_set_style_pad_all(black_screen, 0, LV_STATE_DEFAULT);
  lv_obj_set_style_radius(black_screen, 0, LV_STATE_DEFAULT);
  lv_obj_add_flag(black_screen, LV_OBJ_FLAG_CLICKABLE);
  lv_obj_add_event_cb(black_screen, black_screen_click_event_handler, LV_EVENT_SHORT_CLICKED, NULL);
  play_window.screen = black_screen;

  // 创建底部容器
  lv_obj_t *cont = lv_obj_create(black_screen);
  lv_obj_set_size(cont, lcd_w, PLAY_WINDOW_BOTTOM_CONT_HEIGHT);
  lv_obj_align(cont, LV_ALIGN_BOTTOM_MID, 0, 0);
  lv_obj_clear_flag(cont, LV_OBJ_FLAG_SCROLLABLE); // 禁止滚动
  lv_obj_set_style_radius(cont, 0, LV_STATE_DEFAULT);
  lv_obj_set_style_border_width(cont, 0, LV_STATE_DEFAULT);                  // 无边框
  lv_obj_set_style_bg_color(cont, lv_color_hex(0x000000), LV_STATE_DEFAULT); // 背景黑色
  play_window.bottom_cont = cont;

  // 创建底部暂停播放
  do
  {
    const lv_img_dsc_t *icon[] = {&playing, &list};
    lv_obj_t **imgs[] = {&play_window.pause_img, &play_window.list_img};
    lv_event_cb_t img_cbs[] =
    {
        play_window_bottom_pause_btn_click_event_cb,
        play_window_bottom_list_btn_click_event_cb,
    };

    for (int i = 0; i < sizeof(icon) / sizeof(icon[0]); i++) // 创建5img按钮
    {
      imgs[i][0] = lv_img_create(cont); // img按钮
      lv_img_set_src(imgs[i][0], icon[i]);
      lv_obj_set_style_img_opa(imgs[i][0], LV_OPA_60, LV_STATE_DEFAULT);    // 松开时透明度
      lv_obj_set_style_img_opa(imgs[i][0], LV_OPA_COVER, LV_STATE_PRESSED); // 按下时透明度
      lv_obj_add_flag(imgs[i][0], LV_OBJ_FLAG_CLICKABLE);
      lv_obj_add_event_cb(imgs[i][0], img_cbs[i], LV_EVENT_SHORT_CLICKED, NULL);

      if (i != 0)
        lv_obj_align_to(imgs[i][0], imgs[i - 1][0], LV_ALIGN_OUT_RIGHT_MID, 10, 0);
      else
        lv_obj_align(imgs[i][0], LV_ALIGN_LEFT_MID, 0, 0);
    }
  } while (0);

  // 创建视频进度滑块条
  lv_obj_t *slider = lv_slider_create(cont);
  lv_obj_set_size(slider, 500, 10);
  lv_obj_set_style_bg_color(slider, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(slider, LV_OPA_60, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(slider, lv_color_hex(0x82cef5), LV_PART_INDICATOR | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(slider, lv_color_hex(0x82cef5), LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_align_to(slider, play_window.list_img, LV_ALIGN_OUT_RIGHT_MID, 15, 0);
  lv_obj_add_event_cb(slider, video_progress_slider_event_cb, LV_EVENT_RELEASED, NULL);
  lv_obj_add_event_cb(slider, video_progress_slider_event_cb, LV_EVENT_PRESSING, NULL);
  lv_obj_add_event_cb(slider, video_progress_slider_event_cb, LV_EVENT_PRESSED, NULL);
  play_window.prog_slider = slider;

  // 创建视频文件名标签
  lv_obj_t *video_name_label = lv_label_create(cont);
  lv_obj_set_style_text_font(video_name_label, &lv_font_miao_18, LV_STATE_DEFAULT);
  lv_obj_set_style_text_color(video_name_label, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_label_set_text(video_name_label, "无视频播放");
  lv_obj_align_to(video_name_label, slider, LV_ALIGN_OUT_TOP_LEFT, 0, -5);
  play_window.video_label = video_name_label;

  // 创建视频进度时间标签
  lv_obj_t *time_label = lv_label_create(cont);
  lv_obj_set_style_text_font(time_label, &lv_font_miao_16, LV_STATE_DEFAULT);
  lv_obj_set_style_text_color(time_label, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_label_set_text(time_label, "00:00/00:00");
  lv_obj_set_user_data(slider, time_label);
  lv_obj_align_to(time_label, slider, LV_ALIGN_OUT_RIGHT_MID, 15, 0);
  play_window.time_label = time_label;

  //创建视频音量标签
  lv_obj_t *volume_img = lv_img_create(cont);
  lv_img_set_src(volume_img, &volume);
  lv_obj_align_to(volume_img, time_label, LV_ALIGN_OUT_RIGHT_MID, 10, 0);

  //创建视频音量滑块条
  slider = lv_slider_create(cont);
  lv_slider_set_range(slider, 0, 40);
  lv_obj_set_size(slider, 150, 10);
  lv_obj_set_style_bg_color(slider, lv_color_hex(0xe6e6e6), LV_STATE_DEFAULT);
  lv_obj_set_style_bg_opa(slider, LV_OPA_60, LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(slider, lv_color_hex(0x82cef5), LV_PART_INDICATOR | LV_STATE_DEFAULT);
  lv_obj_set_style_bg_color(slider, lv_color_hex(0x82cef5), LV_PART_KNOB | LV_STATE_DEFAULT);
  lv_obj_align_to(slider, play_window.list_img, LV_ALIGN_OUT_RIGHT_MID, 15, 0);
  lv_obj_add_event_cb(slider, volume_slider_event_cb, LV_EVENT_RELEASED, NULL);
  lv_obj_add_event_cb(slider, volume_slider_event_cb, LV_EVENT_PRESSING, NULL);
  lv_obj_align_to(slider, volume_img, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
  play_window.volume_slider = slider;

  int volume_cur = 0;

  if(gui_opts.video_get_volume != NULL)
    volume_cur = gui_opts.video_get_volume();

  lv_slider_set_value(slider, volume_cur, LV_ANIM_OFF);
}

/**
 *@brief 设置视频播放进度显示
 */
void video_gui_set_progress(int cur, int total)
{
  if (play_window.screen == NULL || video_screen_is_clean == true)
    return;

  lv_slider_set_range(play_window.prog_slider, 0, total);
  if (video_slider_pressed != true) // 未按下时设置
    lv_slider_set_value(play_window.prog_slider, cur, LV_ANIM_OFF);

  lv_label_set_text_fmt(play_window.time_label, "%d:%d/%d:%d", cur / 60, cur % 60, total / 60, total % 60);
}

/**
 *@brief 释放播放窗口
 */
void video_gui_del_play_window(void)
{
  lv_obj_del_async(play_window.screen);
  play_window.screen = NULL;
}

/**
 *@brief 释放界面UI
 */
void video_gui_release(void)
{
  lv_obj_t *btn = NULL;

  while ((btn = lv_obj_get_child(video_list, -1)) != NULL)
  {
    void *video_name = lv_obj_get_user_data(btn);
    if (video_name != NULL)
      free(video_name);

    lv_obj_del(btn);
  }

  lv_obj_del(back_img);
}

/**
 *@brief 长按拖动控件事件函数
 */
static void drag_event_handler(lv_event_t *e)
{
  lv_obj_t *obj = lv_event_get_target(e);

  lv_indev_t *indev = lv_indev_get_act();
  if (indev == NULL)
    return;

  lv_point_t vect;
  lv_indev_get_vect(indev, &vect);

  lv_coord_t x = lv_obj_get_x(obj) + vect.x;
  lv_coord_t y = lv_obj_get_y(obj) + vect.y;
  lv_obj_set_pos(obj, x, y);
}

/**
 *@brief 视频列表按钮点击事件回调函数
 */
static void video_list_btn_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);
    const char *video_name = lv_obj_get_user_data(btn);

  video_gui_create_play_window(); // 创建播放窗口
  video_screen_is_clean = false;   //标记未清屏

  // 创建定时器，清除变量
  lv_timer_t *clear_flag_timer = lv_timer_create(set_clearscreen_flag_timer_cb, 150, NULL);
  lv_timer_set_repeat_count(clear_flag_timer, 1);    //单次定时器

  // 创建清屏定时器，清屏
  clear_screen_timer = lv_timer_create(clear_screen_timer_cb, 500, NULL);
  lv_timer_set_repeat_count(clear_screen_timer, 1);    //单次定时器

  lv_label_set_text(play_window.video_label, video_name);

  if (btn == playing_video_btn) // 是当前正在播放的视频
    return;

  if(playing_video_btn != NULL)
  {
    lv_obj_t *img = lv_obj_get_child(playing_video_btn, 0);  
    lv_img_set_src(img, &item_idle);    //修改上一个播放项目图标
  }

  //设置视频list播放项目图标icon
  lv_obj_t *img = lv_obj_get_child(btn, 0);  
  lv_img_set_src(img, &item_playing);

  playing_video_btn = btn;      //保存新的视频list btn

  if (gui_opts.video_play != NULL)
      gui_opts.video_play(video_name);      //新视频播放
}

/**
 *@brief 视频播放底部暂停播放img按钮点击事件回调函数
 */
static void play_window_bottom_pause_btn_click_event_cb(lv_event_t *e)
{
  lv_obj_t *btn = lv_event_get_target(e);

  bool video_state = false;

  if (gui_opts.video_get_state != NULL)
    video_state = gui_opts.video_get_state();

  video_state = !video_state;

  if (video_state == true)
  {
    if (gui_opts.video_play != NULL)
      gui_opts.video_play(NULL);      //传入NULL表示继续播放，而不是新视屏播放
  }
  else
  {
    if (gui_opts.video_pause != NULL)
      gui_opts.video_pause();
  }

  if(clear_screen_timer != NULL)
      lv_timer_reset(clear_screen_timer); //重置清屏定时器

  lv_img_set_src(play_window.pause_img, video_state ? &playing : &pause);
}

/**
 *@brief 视频播放底部列表img按钮点击事件回调函数
 */
static void play_window_bottom_list_btn_click_event_cb(lv_event_t *e)
{
  if(clear_screen_timer != NULL)
    lv_timer_del(clear_screen_timer); //删除清屏定时器

  video_gui_del_play_window(); // 删除播放窗口
}

/**
 *@brief 视频进度滑块条滑动事件函数
 */
static void video_progress_slider_event_cb(lv_event_t *e)
{
  lv_obj_t *slider = lv_event_get_target(e);
  lv_event_code_t e_code = lv_event_get_code(e);

  if (e_code == LV_EVENT_RELEASED)
  {
    video_slider_pressed = false;
    int cur = lv_slider_get_value(slider);

    if (gui_opts.video_set_cur != NULL)
      gui_opts.video_set_cur(cur);
  }
  else if (e_code == LV_EVENT_PRESSED)
  {
    video_slider_pressed = true;
  }
  else if(e_code == LV_EVENT_PRESSING)
  {
    if(clear_screen_timer != NULL)
      lv_timer_reset(clear_screen_timer); //重置清屏定时器
  }
}

/**
 *@brief 音量进度滑块条滑动事件函数
 */
static void volume_slider_event_cb(lv_event_t *e)
{
  lv_obj_t *slider = lv_event_get_target(e);
  lv_event_code_t e_code = lv_event_get_code(e);

  if (e_code == LV_EVENT_RELEASED)
  {
    int v = lv_slider_get_value(slider);

    if (gui_opts.video_set_volume != NULL)
      gui_opts.video_set_volume(v);
  }
  else if(e_code == LV_EVENT_PRESSING)
  {
    if(clear_screen_timer != NULL)
      lv_timer_reset(clear_screen_timer); //重置清屏定时器
  }
}

/**
 *@brief 视频播放窗口点击事件回调函数
 */
static void black_screen_click_event_handler(lv_event_t *e)
{
  //无效化底层容器
  lv_obj_invalidate(play_window.bottom_cont);
  video_screen_is_clean = false;   //标记未清屏

  // 创建定时器，设置变量
  lv_timer_t *clear_flag_timer = lv_timer_create(set_clearscreen_flag_timer_cb, 2500, NULL);
  lv_timer_set_repeat_count(clear_flag_timer, 1);    //单次定时器

  // 创建定时器，清屏
  clear_screen_timer = lv_timer_create(clear_screen_timer_cb, 3000, NULL);
  lv_timer_set_repeat_count(clear_screen_timer, 1);    //单次定时器    
}

/**
 *@brief  设置清屏标志定时器回调函数
 */
static void set_clearscreen_flag_timer_cb(lv_timer_t *t)
{
  video_screen_is_clean = true;     //标记当前已清屏，禁止所有UI绘制
}

/**
 *@brief  清屏定时器回调函数
 */
static void clear_screen_timer_cb(lv_timer_t *t)
{
  clear_screen_timer = NULL;

  if(gui_opts.video_clear_screen != NULL)
    gui_opts.video_clear_screen();
}